package se.webbzon.boltzmann.configuration;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import se.webbzon.boltzmann.debug.Debug;
import se.webbzon.boltzmann.input.Input;

public class Controls {
        
        // The singleton instance of the control configuration
        private static Controls singleton; 
        
        // A collection of all the listeners to the graphic configuration instance
        private final Collection<ControlsListener> listeners;
        
        // A collection of all the available inputs
        private final List<Input> inputs;
        
        // The default input for the control configuration
        private Input input;
        
        /*============================================================
        Constructors
        ============================================================*/
        
        public Controls() {
                listeners = new ArrayList<ControlsListener>();
                inputs = new ArrayList<Input>();
        }
        
        /*============================================================
        Public Methods
        ============================================================*/
        
        /** Returns the singleton instance of the control configuration. **/
        public synchronized static Controls instance() {
                if (singleton == null)
                        singleton = new Controls();
                return singleton;
        }
        
        /** Adds a listener to the control configuration instance. **/
        public boolean addListener(ControlsListener listener) {
                int d;
                Debug.debugCollection(this, listeners);
                return listeners.add(listener);
        }
        
        /** Removes a listener from the control configuration instance. **/
        public boolean removeListener(ControlsListener listener) {
                return listeners.remove(listener);
        }
        
        /** Clears all listeners to the control configuration instance. **/
        public void clearListeners() {
                listeners.clear();
        }
        
        /** Adds an input to the control configuration instance. **/
        public boolean addInput(Input input) {
                if (inputs.add(input)) {
                        for (ControlsListener listener : listeners)
                                listener.onAddInput(input);
                        return true;
                } else
                        return false;
        }
        
        /** Removes an input from the control configuration instance. **/
        public boolean removeInput(Input input) {
                if (inputs.remove(input)) {
                        for (ControlsListener listener : listeners)
                                listener.onRemoveInput(input);
                        if (input == this.input)
                                setInput(null);
                        return true;
                } else
                        return false;
        }
        
        /** Sets the input for the control configuration instance. **/
        public void setInput(Input input) {
                if (input != this.input && inputs.contains(input)) {
                        Input oldInput = this.input;
                        this.input = input;
                        for (ControlsListener listener : listeners)
                                listener.onChangeInput(oldInput,input);
                } 
        }
        
        /** Returns the input for the control configuration instance. 
         * If null is returned then no input is set. **/
        public Input getInput() {
                return input;
        }
        
        /** Returns the number of available inputs. **/
        public int inputs() {
                return inputs.size();
        }
        
        /** Returns the (n+1):th available input. **/
        public Input getInput(int n) {
                return inputs.get(n);
        }

}